#include "p12.h"
#include <iostream>
#include <string>


void print(int x) {
    std::cout << "print(int): " << x << '\n';
}


void print(int* ptr) {
    std::cout << "print(int*): " << static_cast<void*>(ptr) << '\n';
}

/***
 * @description: 这里是为了验证 NULL 在这里如果传入NULL，函数并不知道你传入的是 0 0L ((void*)0)
 * @return {*}
 */
void testNULL() {
    int x {5};
    int* ptr {&x};

    print(0);
    print(ptr);

    // print(NULL);            // ambiguous
    print(nullptr);
}


/***
 * @description: 通过引用返回的对象在函数返回后必须存在，所以这里对象是static，本质就是要保留生存周期
 * @return {*}
 */
const std::string& getProgramName() {
    static const std::string sProgramName { "Calculator" };

    return sProgramName;
}


/***
 * @description: 这里会造成问题，如果多个接口调用ID会导致前面调用的ID也跟随变化，不建议使用非const的传出
 * @return {*}
 */
const int& getNextID() {
    static int sx {0};
    ++sx;
    return sx;
}


int& max(int& x, int& y) {
    return (x > y) ? x : y;
}


void testMaxRef() {
    int a {5};
    int b {6};

    std::cout << "a = " << a << ", b = " << b << '\n';
    max(a, b);
    std::cout << "ptr a addr: " << static_cast<void*>(&a) << '\n';
    std::cout << "ptr b addr: " << static_cast<void*>(&b) << '\n';
    std::cout << "max v addr: " << static_cast<void*>(&max(a, b)) << '\n';


    std::cout << "a = " << a << ", b = " << b << '\n';
}


constexpr std::string_view hello { "Hello" };

constexpr const std::string_view& getConstRef() {
    return hello;
}

/**
 * auto 做类型推断时会丢掉const 和 引用符，所以这里需要注意其使用
 */
void testAutoFunc() {
    auto ref1 { getConstRef() };
    constexpr auto ref2 { getConstRef() };
    auto& ref3{ getConstRef() };
    constexpr const auto& ref4 { getConstRef() };
}
